home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / WIN_PRO / DS-1.ZIP;1 / ICONT.ZIP / UTIL.C < prev   
Encoding:
C/C++ Source or Header  |  1992-02-10  |  8.8 KB  |  472 lines

  1. /*
  2.  *  util.c -- general utility functions.
  3.  */
  4.  
  5. #include <ctype.h>
  6. #include "../h/gsupport.h"
  7. #include "tproto.h"
  8. #include "globals.h"
  9. #include "trans.h"
  10. #include "tree.h"
  11.  
  12.  
  13. extern int optindex;
  14.  
  15. extern char *ofile;
  16.  
  17. /*
  18.  * The following code is operating-system dependent [@util.01].  Define the
  19.  *  characters that terminate a file name prefix.
  20.  */
  21.  
  22. #if PORT
  23. #define Prefix "/"
  24. Deliberate Syntax Error
  25. #endif                    /* PORT */
  26.  
  27. #if AMIGA
  28. #define Prefix "/:"
  29. #endif                    /* AMIGA */
  30.  
  31. #if ARM
  32. #define Prefix ".:"
  33. #endif                    /* ARM */
  34.  
  35. #if ATARI_ST
  36. #define Prefix "/:\\"
  37. #endif                    /* ATARI_ST */
  38.  
  39. #if MSDOS || OS2
  40. #define Prefix "/:\\"
  41. #endif                    /* MSDOS || OS2 */
  42.  
  43. #if MACINTOSH
  44. #define Prefix ":"
  45. #endif                    /* MACINTOSH */
  46.  
  47. #if MVS || VM
  48. #define Prefix ""
  49. #endif                    /* MVS || VM */
  50.  
  51. #if UNIX
  52. #define Prefix "/"
  53. #endif                    /* UNIX */
  54.  
  55. #if VMS
  56. #define Prefix "]:"
  57. #endif                    /* VMS */
  58.  
  59. /*
  60.  * End of operating-system specific code.
  61.  */
  62.  
  63. /*
  64.  * Information about Icon functions.
  65.  */
  66.  
  67. /*
  68.  * Number of arguments.
  69.  */
  70.  
  71.  
  72. /*
  73.  * Names of Icon functions.
  74.  */
  75. char *ftable[] = {
  76. #define FncDef(p,n) Lit(p),
  77. #define FncDefV(p) Lit(p),
  78. #include "../h/fdefs.h"
  79. #undef FncDef
  80. #undef FncDefV
  81.    };
  82.  
  83. int ftbsize = sizeof(ftable)/sizeof(char *);
  84.  
  85. /*
  86.  * alloc - allocate n bytes
  87.  */
  88.  
  89. pointer alloc(n)
  90. unsigned int n;
  91.    {
  92.    pointer a;
  93.  
  94.    if (!(a = malloc((msize)n)))
  95.       quit("out of memory");
  96.    return a;
  97.    }
  98.  
  99. /*
  100.  * salloc - allocate and initialize string 
  101.  */
  102.  
  103. char *salloc(s)
  104. char *s;
  105.    {
  106.    char *tmp = (char *)alloc((unsigned int)(strlen(s)+1));
  107.    strcpy(tmp,s);
  108.    return tmp;
  109.    }
  110.  
  111. /*
  112.  * tcalloc - allocate and zero m*n bytes
  113.  */
  114. pointer tcalloc(m,n)
  115. unsigned int m, n;
  116.    {
  117.    pointer a;
  118.  
  119.    if (!(a = calloc(m,n)))
  120.       quit("out of memory");
  121.    return a;
  122.    }
  123.  
  124. /*
  125.  * fparse - break a file name down into component parts.
  126.  *  Result is a pointer to a struct of static pointers good until the next call.
  127.  */
  128. struct fileparts *fparse(s)
  129. char *s;
  130.    {
  131.    static char buf[MaxFileName+2];
  132.    static struct fileparts fp;
  133.    int n;
  134.    char *p, *q;
  135.  
  136. #if ARM
  137.    static char buf[MaxFileName+2];
  138.    static struct fileparts fp;
  139.    char *p;
  140.    char *ext = 0;
  141.    char *extend = 0;
  142.    char *dirend = 0;
  143.    char *s1;
  144.    char *bp = buf;
  145.  
  146.    /* First, skip any filing system prefix */
  147.    s1 = index(s,':');
  148.    if (s1 == NULL)
  149.       s1 = s;
  150.    else
  151.       ++s1;
  152.  
  153.    /* Now, scan backwards through the filename, looking for dots.
  154.     * Record the positions of the final two, for later use.
  155.     */
  156.    p = s1 + strlen(s1);
  157.    fp.name = 0;
  158.    
  159.    while (--p > s1)
  160.    {
  161.          if (*p != '.')
  162.             continue;
  163.  
  164.       if (fp.name == NULL)
  165.       {
  166.          fp.name = p + 1;
  167.          extend = p;
  168.       }
  169.       else
  170.       {
  171.          ext = p + 1;
  172.          dirend = p;
  173.          break;
  174.       }
  175.    }
  176.  
  177.    /* This is the simple case. The filename is a simple name, with no
  178.     * directory part. The extension is therefore null, and the directory
  179.     * is just the filing system prefix, if any.
  180.     */
  181.    if (fp.name == NULL)
  182.    {
  183.       fp.name = s1;
  184.  
  185.       if (s1 == s)
  186.       {
  187.          fp.ext = "";
  188.          fp.dir = "";
  189.       }
  190.       else
  191.       {
  192.          fp.ext = "";
  193.          strncpy(buf, s, s1 - s);
  194.          buf[s1-s] = '\0';
  195.          fp.dir = buf;
  196.       }
  197.  
  198.       return &fp;
  199.    }
  200.  
  201.    /* Now worry about the more complicated cases. First, check the
  202.     * supposed extension, to see if it is one of the valid cases,
  203.     * SourceSuffix, U1Suffix, U2Suffix, or USuffix. For this code
  204.     * to work, these four defined values must start with a dot, and
  205.     * be all in lower case.
  206.     */
  207.    *buf = '.';
  208.    bp = buf + 1;
  209.  
  210.    for (p = ext ? ext : s1; p < extend; ++p)
  211.    {
  212.       *bp++ = tolower(*p);
  213.    }
  214.  
  215.    *bp++ = '\0';
  216.  
  217.    if (strcmp(buf,SourceSuffix) == 0 || strcmp(buf,U1Suffix) == 0
  218.     || strcmp(buf,U2Suffix) == 0 || strcmp(buf,USuffix) == 0)
  219.    {
  220.       fp.ext = buf;
  221.    }
  222.    else
  223.    {
  224.       fp.ext = "";
  225.       bp = buf;
  226.       dirend = extend;
  227.    }
  228.  
  229.    /* We now have the name and extension sorted out. So we just need
  230.     * to copy the directory part into buf (at bp), and set fp.dir.
  231.     */
  232.    if (dirend == NULL)
  233.    {
  234.       if (s1 == s)
  235.          fp.dir = "";
  236.       else
  237.       {
  238.          fp.dir = bp;
  239.  
  240.          while (s < s1)
  241.             *bp++ = *s++;
  242.  
  243.          *bp = '\0';
  244.       }
  245.    }
  246.    else
  247.    {
  248.       fp.dir = bp;
  249.  
  250.       while (s <= dirend)
  251.          *bp++ = *s++;
  252.  
  253.       *bp = '\0';
  254.    }
  255.  
  256.    return &fp;
  257.  
  258. #else                    /* ARM */
  259.  
  260. #if MVS
  261.    static char extbuf [MaxFileName+2] ;
  262.  
  263.    p = index(s, '(');
  264.    if (p) {
  265.       fp.member = p+1;
  266.       memcpy(extbuf, s, p-s);
  267.       extbuf [p-s]  = '\0';
  268.       s = extbuf;
  269.    }
  270.    else fp.member = s + strlen(s);
  271. #endif                    /* MVS */
  272.  
  273.    q = s;
  274.    fp.ext = p = s + strlen(s);
  275.    while (--p >= s) {
  276.       if (*p == '.' && *fp.ext == '\0')
  277.          fp.ext = p;
  278.       else if (index(Prefix,*p)) {
  279.          q = p+1;
  280.          break;
  281.          }
  282.       }
  283.    fp.dir = buf;
  284.    n = q - s;
  285.    strncpy(fp.dir,s,n);
  286.    fp.dir[n] = '\0';
  287.    fp.name = buf + n + 1;
  288.    n = fp.ext - q;
  289.    strncpy(fp.name,q,n);
  290.    fp.name[n] = '\0';
  291.    return &fp;
  292.    }
  293. #endif                    /* ARM */
  294.  
  295. /*
  296.  * makename - make a file name, optionally substituting a new dir and/or ext
  297.  */
  298. char *makename(dest,d,name,e)
  299. char *dest, *d, *name, *e;
  300.    {
  301.    struct fileparts fp;
  302.    fp = *fparse(name);
  303.    if (d != NULL)
  304.       fp.dir = d;
  305.    if (e != NULL)
  306.       fp.ext = e;
  307.  
  308. #if ARM
  309.    {
  310.       char *p = (*fp.ext ? fp.ext + 1 : "");
  311.       sprintf(dest, "%s%s%s%s", fp.dir, p, (*p ? "." : ""), fp.name);
  312.    }
  313.  
  314. #else                    /* ARM */
  315.  
  316. #if MVS
  317. #if SASC
  318.    {
  319.       char *colons;
  320.       colons = strstr(fp.name, ":::");
  321.       if (colons) {
  322.          memcpy(colons+1, e+1, 2);
  323.          fp.ext = "";
  324.       }
  325.    }
  326. #endif                    /* SASC */
  327.    if (*fp.member)
  328.       sprintf(dest,"%s%s%s(%s", fp.dir, fp.name, fp.ext, fp.member);
  329.    else
  330. #endif                    /* MVS */
  331.  
  332.    sprintf(dest,"%s%s%s",fp.dir,fp.name,fp.ext);
  333. #endif                    /* ARM */
  334.  
  335.    return dest;
  336.    }
  337.  
  338. /*
  339.  * quit - immediate exit with error message
  340.  */
  341.  
  342. novalue quit(msg)
  343. char *msg;
  344.    {
  345.    quitf(msg,"");
  346.    }
  347.  
  348. /*
  349.  * quitf - immediate exit with message format and argument
  350.  */
  351. novalue quitf(msg,arg)
  352. char *msg, *arg;
  353.    {
  354.  
  355.  
  356.    extern char *progname;
  357.    fprintf(stderr,"%s: ",progname);
  358.    fprintf(stderr,msg,arg);
  359.    fprintf(stderr,"\n");
  360.  
  361. #ifndef VarTran
  362.    if (ofile)
  363.       unlink(ofile);            /* remove bad icode file */
  364. #endif                    /* VarTran */
  365.  
  366.    exit(ErrorExit);
  367.    }
  368.  
  369. /*
  370.  * tsyserr is called for fatal errors.  The message s is produced and the
  371.  *  translator exits.
  372.  */
  373. novalue tsyserr(s)
  374. char *s;
  375.    {
  376.  
  377.  
  378.    if (tok_loc.n_file)
  379.       fprintf(stderr, "File %s; ", tok_loc.n_file);
  380.    fprintf(stderr, "Line %d # %s\n", in_line, s);
  381.  
  382.    exit(ErrorExit);
  383.    }
  384.  
  385.  
  386. /*
  387.  * round2 - round an integer up to the next power of 2.
  388.  */
  389. unsigned int round2(n)
  390. unsigned int n;
  391.    {
  392.    unsigned int b = 1;
  393.    while (b < n)
  394.       b <<= 1;
  395.    return b;
  396.    }
  397.  
  398.  
  399. /*
  400.  * sizearg - process -S command option.
  401.  */
  402.  
  403. struct keyptr {            /* structure for listing option chars */
  404.    char *cmd;                /* option character(s) */
  405.    unsigned int *valp;            /* pointer to value word */
  406.    };
  407.  
  408. static struct keyptr keytable[] = {    /* maps keys to store addresses */
  409.  
  410. #define Size(cmd,vname,defalt) cmd, &vname,
  411. #define MinSize(x,y,z)
  412. #include "sizes.h"            /* initialize from "sizes.h" data */
  413. #undef Size
  414. #undef MinSize
  415.    0, 0,                /* terminate with null entry */
  416.    };
  417.  
  418. novalue sizearg(arg,argv)
  419. char *arg;
  420. char **argv;
  421.    {
  422.    struct keyptr *k;            /* key table pointer */
  423.    char *s;                /* value string pointer */
  424.    int v;                /* option value */
  425.  
  426.    for (k = keytable; k->cmd; k++)    /* search for key match */
  427.       if (arg[0] == k->cmd[0] && (arg[0] != 'h' || arg[1] == k->cmd[1]))
  428.          break;
  429.  
  430.    if (k->cmd == NULL)            /* abort if not found */
  431.       quitf("unrecognized -S option: -S%s",arg);
  432.  
  433.    if (arg[0] == 'h')
  434.       s = &arg[2];            /* find value */
  435.    else
  436.       s = &arg[1];
  437.       
  438.    if (*s == '\0') {            /* if value is in next arg */
  439.       s = argv[optindex++];
  440.       if (s == NULL)
  441.          quitf("missing value: -S%s", arg);
  442.       }
  443.  
  444.    v = (int)atol(s);                /* convert integer -- check */
  445.    if (v <= 0)
  446.       quitf("illegal value: -S%s", arg);
  447.    *k->valp = v;            /* store result */
  448.    }
  449.  
  450.  
  451. /*
  452.  * smatch - case-insensitive string match - returns nonzero if they match
  453.  */
  454. int smatch(s,t)
  455. char *s, *t;
  456.    {
  457.    char a, b;
  458.    for (;;) {
  459.       while (*s == *t)
  460.          if (*s++ == '\0')
  461.             return 1;
  462.          else
  463.             t++;
  464.       a = *s++;
  465.       b = *t++;
  466.       if (isupper(a))  a = tolower(a);
  467.       if (isupper(b))  b = tolower(b);
  468.       if (a != b)
  469.          return 0;
  470.       }
  471.    }
  472.